// ----------------------------------
function generateEdge(vertices, edge){
// ----------------------------------
		// Get our starting vertex
		var startI = edge[0];
		var startV = vertices[startI];
		var startS = startV[0] + " " + startV[1];

		// Get out ending vertex
		var endI = edge[1];
		var endV = vertices[endI];
		var endS = endV[0] + " " + endV[1];

		return "M " + startS + " L " + endS + " ";
}

// ----------------------------
function vertexToString(vertex){
// ----------------------------
	return "" + vertex[0] + " " + vertex[1];
}

// ---------------------------------------------------
function generateAdjacencyLists(vertices, edges, face){
// ---------------------------------------------------
	// Initialize the array of arrays
	adjacencyLists = new Array(vertices.length);
	for(i = 0; i < vertices.length; ++i){
		adjacencyLists[i] = new Array();
	}

	// Populate the adjacency lists for the vertices
	for(i = 0; i < face.length; ++i){
		v1 = edges[face[i]][0];
		v2 = edges[face[i]][1];

		adjacencyLists[v1].push(v2);
		adjacencyLists[v2].push(v1);
	}

	return adjacencyLists;
}

// ---------------------------------------------------------
function generateFace(vertices, edges, face, adjacencyLists){
// ---------------------------------------------------------
	
	// Start at the first vertex
	edge1 = edges[face[0]];
	vS = edge1[0];
	v = vS;
	vP = -1;

	// Initialize our face path
	facePath = "M" + vertices[vS][0] + " " + vertices[vS][1] + " ";

	// Loop around the face	
	do{
		vC1 = adjacencyLists[v][0];
		vC2 = adjacencyLists[v][1];
		vPP = v;
		v = (vP != vC1) ? vC1 : vC2;
		vP = vPP;

		// Add the vertex to the path
		facePath += "L" + vertices[v][0] + " " + vertices[v][1] + " ";

	}while(v != vS)	
	
	return facePath;
}

// -------------------------------------------------------
function drawCellComplex(cell_complex, paper, scaleFactor){
// -------------------------------------------------------
	// Pull put the various pieces
	vertices = cell_complex[0];
	edges = cell_complex[1];
	faces = cell_complex[2];

	// Scale the vertices
	//scaleFactor = 15;	
	offX = 5;
	offY = 5;
	for(i = 0; i < vertices.length; ++i){
		vertices[i][0] = (vertices[i][0] * scaleFactor) + offX;
		vertices[i][1] = (vertices[i][1] * scaleFactor) + offY;
	}

	// Create a data structure to keep track of which edges we've drawn
	edgesDrawn = new Array();
	for(i = 0; i < edges.length; ++i){
		edgesDrawn[i] = false;
	}

	// Draw (and fill) the faces
	for(i = 0; i < faces.length; ++i){
		face = faces[i];	
		adjacencyLists = generateAdjacencyLists(vertices, edges, face);
		facePath = generateFace(vertices, edges, face, adjacencyLists);

		face = paper.path(facePath);
		face.attr("fill", "gray");

		// Mark the edges as drawn
		for(j = 0; j < face.length; ++j){
			edgesDrawn[face[j]] = true;
		}
	}

	// Draw the edges
	edgePath = "";
	for(i = 0; i < edges.length; ++i){
		if(!edgesDrawn[i]){
			edge = edges[i];
			edgePath += generateEdge(vertices, edge);
		}
	}
	path = paper.path(edgePath);
	path.attr("stroke", "black");

	// Draw the vertices
	for(i = 0; i < vertices.length; ++i){
		// Draw a circle at the vertex
		vCircle = paper.circle(vertices[i][0], vertices[i][1], 1);
		vCircle.attr("fill", "black");
	}
}
